package local

import (
	"database/sql/driver"
	"encoding/json"
	"fmt"
	"strconv"
	"strings"
)

/* ------
自定义 LocalInt:
	1. 处理前端传 null、"" 时过滤筛选条件。
	2. 与 int 转换: t.Int.(int) 、 LocalInt{Int:1}
	3. 自定义函数:
		NotNil()			// 是否为空
		GetValue()			// 获取值
		GetQueryNilStr()	// 查询操作字段是 NULL 时能用。
------ */

// LocalInt 自定义 Int。前端传值为 null, 或数字字符串 时,正常处理存入数据库为 NULL
type LocalInt struct {
	Int interface{}
}

// UnmarshalJSON 解码
func (t *LocalInt) UnmarshalJSON(b []byte) error {
	fmt.Println("--- UnmarshalJSON:", b)
	str := strings.Trim(string(b), "\"")
	num, err := strconv.Atoi(str)
	if err == nil {
		t.Int = num
	} else {
		t.Int = nil
	}
	return nil
}

// MarshalJSON 编码
func (t LocalInt) MarshalJSON() ([]byte, error) {
	b, err := json.Marshal(t.Int)
	return b, err
}

// Value 保存到数据库时调用。
func (t LocalInt) Value() (driver.Value, error) {
	return t.Int, nil
}

// Scan 接受数据库数据时调用。
func (t *LocalInt) Scan(v interface{}) error {
	value, ok := v.(int)
	if ok {
		*t = LocalInt{Int: value}
	} else {
		*t = LocalInt{Int: nil}
	}
	return nil
}

// NotNil 判断不为空。LocalInt 只有 nil 返回 false 。
func (t LocalInt) NotNil() bool {
	if t.Int == nil {
		return false
	}
	return true
}

// GetValue 没有默认为 0 。
// 数据库中字段类型为 tinyint(3) 用 LocalInt 时, Value() 存储时报错: sql: converting argument $5 type: non-Value type int returned from Value 原因未知, 故添加此函数。
func (t *LocalInt) GetValue() int {
	value := 0
	if t.Int != nil {
		value = t.Int.(int)
	}
	return value
}

// GetQueryNilStr 获取 query 条件
func (t LocalInt) GetQueryNilStr(column string) string {
	if t.Int == nil {
		return column + " is NULL"
	}
	return fmt.Sprintf(column+" = '%d'", t.Int.(int))
}
